﻿
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.Threading.Tasks;
using CK.Sprite.FileStorage.Application;

namespace CK.Sprite.FileStorage
{
    public class LocalStorageProvider : StorageProvider
    {
        public LocalStorageProvider(FileStorgeOptions options) : base(options)
        {
        }

        public override async Task<string[]> StoreAsync(string fileName, string ext, string groupName = null)
        {
            var newFileName = CreateNewFileName(ext);
            var filePath = Path.Combine(Options.LocalStoragePathParent, Options.LocalStoragePath, newFileName);
            await Task.Run(() => File.Copy(fileName, filePath));
            return CreateResult(newFileName);
        }

        public override async Task<string[]> StoreAsync(Stream input, string ext, string groupName = null)
        {
            var newFileName = CreateNewFileName(ext);
            var filePath = Path.Combine(Options.LocalStoragePathParent, Options.LocalStoragePath, newFileName);

            using (var output = new FileStream(filePath, FileMode.CreateNew))
            using(input)
            {
                input.Seek(0, SeekOrigin.Begin);
                var buffer = new byte[input.Length];
                await input.ReadAsync(buffer, 0, buffer.Length);
                await output.WriteAsync(buffer, 0, buffer.Length);
            }
            return CreateResult(newFileName);
        }

        private string CreateNewFileName(string ext)
        {
            var month = DateTime.Now.ToString("yyyyMM");
            var filePath = Path.Combine(Options.LocalStoragePathParent, Options.LocalStoragePath, month);
            if (!Directory.Exists(filePath)) {
                try
                {
                    Directory.CreateDirectory(filePath);
                }
                catch (Exception ex)
                {
                    throw new DirectoryNotFoundException("can not create path: " + filePath+". "+ex.Message);
                }
            }
            return Path.Combine(month, Guid.NewGuid().ToString("N") + "." + ext);
        }

        public string[] CreateResult(string newFileName)
        {
            newFileName = newFileName.Replace("\\", UrlSeparator);
            return new[]
            {
                string.Join(UrlSeparator, Options.HttpDomain, Options.LocalStoragePath, newFileName),
                string.Join(UrlSeparator, Options.LocalStoragePath, newFileName)
            };
        }

        public override Task<int> DownloadFileAsync(string remoteFilename, string localFilename, string groupName = null)
        {
            throw new NotImplementedException();
        }

        public override Task<int> DeleteFileAsync(string remoteFilename, string groupName = null)
        {
            throw new NotImplementedException();
        }

        public override string CalculateDownServerPath(string serverPath, string fileName)
        {
            throw new NotImplementedException();
        }
    }
}